/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

/*
=================================== 菜单创建示例 =================================
void f_on_菜单项函数模板(C_Widget* self, const std::wstring name, uint16 id) {
	if (name == L"名称") { }
}

	S_菜单创建参数 菜单创建参数 = {
		f_on_菜单项函数模板, {
			{L"菜单项1", "", &创建参数},
			{L"菜单项2", "", &创建参数},
		}
	};

	auto* menu = f_ui_创建菜单(e_纵向, 菜单创建参数, ctx);
	f_ui_打开菜单(menu, C_Widget::g_鼠标.gPos);
*/



#include "Widget.h"
#include "Input/Input.h"

//#include "实例部件/布局.h"
#include "core/文档文本.h"
#include "场景/场景.h"
#include "实例部件/ui菜单.h"

#include "ui绘制模板.h"
#include "ui绘制工具_组合部件.h"




#define DEF_struct单色绘制ID(name)				\
	typedef struct {							\
		uint16 mID_##name##绘制变换;			\
		uint16 mID_##name##绘制变换;			\
		uint16 mID_##name##绘制变换;			\
	};											\
	

struct S_嵌套UI部件 {
	C_Widget* m_部件;
	std::vector<S_嵌套UI部件> m_子集;
};








//层级UI部件管理  和绘制数据初始化
C_Widget管理*	f_create组件管理(S_UI创建环境& Ctx);
void			f_release组件管理(C_Widget管理* gm);


//void			f_连接绘制函数(C_Widget* w);
//void			f_注册按键(C_Widget* w, uint8 key, uint8 aNum, E_控制键* 控制键, uint8 cNum);

C_Widget* f_创建拖拽面板(const vec2& pos, const vec2& size);








//S_布局器* f_创建排列布局(std::vector<bool>, float32 间隔, E_方向 方向 = E_方向::e_纵向);
C_Widget* f_创建填充布局(const vec2& pos, const vec2& size, const vec4& 边距);
C_Widget* f_创建分割布局(const vec2& pos, const vec2& size, E_方向 方向 = E_方向::e_纵向);
C_Widget* f_创建框架布局(const vec2& pos, const vec2& size, const vec4& 边距);


C_Widget* f_创建根部件(const vec2& 位置比, const vec2& 大小比, E_布局方式 方式);
C_Widget*				f_ui_创建分割窗口(const std::vector<C_Widget*>& ws, E_方向 dir, const std::vector<float32>& 分割比, S_UI创建环境& ctx);
E_方向					f_ui_get分割框排列方向(C_Widget* self);
std::vector<float32>	f_ui_get分割框分割比例(C_Widget* self);
std::vector<C_Widget*>	f_ui_get分割框页面组件(C_Widget* self);


//C_Widget* f_创建分割窗口(const std::vector<S_嵌套UI部件>& ws, E_方向 dir, const std::vector<float32>& 分割比, S_UI创建环境& ctx);
C_Widget* f_ui_创建滚动框(S_UI创建环境& ctx, bool 横向滚动条, bool 纵向滚动条, C_Widget* view);
void f_ui_滚动框安装视口组件(C_Widget* 滚动框, C_Widget* view);


C_Widget* f_散列视口(const vec2& pos, const vec2& size, S_UI创建环境& ctx);

C_Widget*	f_ui_创建3D视口(S_Scene* scene, const vec2& size, S_UI创建环境& ctx, S_设备环境& Ctx3D);
void		f_ui_3D视口绑定场景更新回调(C_Widget* self, fp_Widget更新 func);
void		f_UI_切换3D视口渲染模式(C_Widget* self, E_物体显示模式 type);


C_Widget* f_ui_创建菜单(E_方向 dir, S_菜单创建参数& ini, S_UI创建环境& ctx);
C_Widget* f_ui_创建列表(E_列表显示模式 模式, S_UI创建环境& ctx);
void           f_ui_列表框_添加列表项(C_Widget* self, const S_列表填充数据& data, int32 位置);
int32          f_ui_列表框_移除列表项(C_Widget* self, int32 位置);
void           f_ui_列表框_填充(C_Widget* self, const std::vector<S_列表填充数据>& data);
int32          f_ui_列表框_取当前选中ID(C_Widget* self);
S_列表填充数据 f_ui_列表框_取当前选中项(C_Widget* self);
S_列表填充数据 f_ui_列表框_取选(C_Widget* self, int32 id);
uint32         f_ui_列表框_删除项(C_Widget* self, int32 s, int32 e = -1);
void           f_ui_列表框_设置项(C_Widget* self, int32 位置, const S_列表填充数据& data);
uint32         f_ui_列表框_取项数量(C_Widget* self);
void           f_ui_列表框_绑定项选中回调(C_Widget* self, fp_列表项选中回调_str call);


C_Widget*	f_ui_创建多页面(S_UI创建环境& ctx, E_方向 标签方向, std::vector<C_Widget*>& ws);
C_Widget*	f_ui_创建多页面(S_UI创建环境& ctx, E_方向 标签方向, std::vector<std::wstring>& ws);
E_方向		f_ui_get多页面标签方向(C_Widget* self);
std::vector<C_Widget*> f_ui_get多页面所有页面(C_Widget* self);

C_Widget* f_ui_创建图像视口(S_UI创建环境& ctx, uint8 缓存数量 = 3);
C_Widget* f_ui_创建按钮(S_UI创建环境* ctx, S_Props* op);
C_Widget* f_ui_创建bool值编辑框(S_UI创建环境& ctx, S_Props& prop, fp_Widget布尔值回调 func = nullptr);
C_Widget* f_ui_创建数值编辑框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建vec编辑框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建枚举选择框(S_UI创建环境& ctx, S_Props& prop, E_方向 方向);
C_Widget* f_ui_创建编辑框(S_UI创建环境& ctx, fp_Widget文本回调 f文本输入, fp_Widget文本输入完成 f输入完成, std::string 字体名称);
C_Widget* f_ui_创建可编辑文本下拉框(S_UI创建环境& ctx);
C_Widget* f_ui_创建路径编辑框(S_UI创建环境& ctx, C_Widget* 对话框, fp_Widget绘制调整回调 绘制调整回调);

C_Widget* f_ui_创建颜色选框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建多选框(S_UI创建环境& ctx, S_Props& prop, uint8 键码, E_方向 绘制方向 = E_方向::e_横向);

C_Widget*		f_ui_创建下拉列表(S_UI创建环境& ctx, bool 可编辑 = true, bool 拷贝按钮 = false);
void			f_ui_绑定下拉列表属性(C_Widget* self, S_Props& prop);
void            f_ui_设置下拉列表项(C_Widget* self, int32 id);
std::wstring	f_ui_get下拉列表文本(C_Widget* self);



C_Widget* f_ui_创建超级列表编辑框(S_UI创建环境& ctx, bool 项名称编辑 = true, bool 列表项编辑 = false);
void      f_ui_绑定超级列表编辑框属性(C_Widget* self, S_Props& prop);


C_Widget*	f_ui_创建全屏画布(S_UI创建环境& ctx, C_Widget管理* gm);
void		f_ui_销毁全屏画布(C_Widget* self);


C_Widget* f_ui_创建弹出面板(S_UI创建环境& ctx, E_方向 方向, bool 搜索框);
void f_ui_添加弹出面板菜单项(C_Widget* self, const S_列表填充数据& item, uvec2 组);
void f_ui_删除弹出面板菜单项(C_Widget* self, ivec2 id);
void f_ui_弹出面板项回调绑定(C_Widget* self, fp_列表项选中回调 fn);

C_Widget* f_ui_创建扩展弹出菜单(S_UI创建环境& ctx, E_方向 布局方向, bool 搜索框);
void f_ui_添加扩展弹出菜单项(C_Widget* self, const S_列表填充数据& item, const uvec2& 组);
void f_ui_删除扩展弹出菜单项(C_Widget* self, const ivec2& id);
void f_ui_绑定扩展弹出菜单项回调绑定(C_Widget* self, fp_列表项选中回调 fn);



void		f_ui_set枚举选择框(C_Widget* self, E_方向 方向);

//C_Widget*  f_ui_创建文本编辑框(S_UI创建环境& ctx);

C_Widget*    f_ui_创建行文本编辑框(S_UI创建环境& ctx);
std::wstring f_ui_取行编辑框文本(C_Widget* self);
void         f_ui_bind行编辑框属性(C_Widget* self, S_Props& p);
void         f_ui_bind编辑框完成回调(C_Widget* self, fp_Widget文本输入完成 f输入完成);


C_Widget*	f_ui_创建拾色器(S_UI创建环境& ctx, S_Props& prop);
void		f_ui_拾色器绑定属性(C_Widget* self, S_Props& prop);


C_Widget* f_ui_创建快捷键编辑框(S_UI创建环境& ctx);
void f_ui_快捷键编辑框绑定属性(C_Widget* self, S_Props& prop);



C_Widget* f_ui_创建卡片框(S_UI创建环境& ctx);


void f_ui_连接vecGPU参数修改回调(C_Widget* w, fp_Widget变换修改 fc);
void f_ui_连接vec3GPU编辑回调(C_Widget* w, fp_Widget文本回调 f文本输入, fp_Widget文本输入完成 f输入完成, fp_Widget鼠标按键 f鼠标点击);

//'指定层级' 0 表示当前部件 1则代表当前部件的子部件
void f_ui_连接鼠标移入移出回调(C_Widget* self, fp_Widget鼠标 in, fp_Widget鼠标 out, const uint32 指定层级, uint32 depth = 0);

//指定部件包括所有子部件引用画布

/*C_Widget* f_ui_创建i8值编辑框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建ui8值编辑框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建i32值编辑框(S_UI创建环境& ctx, S_Props& prop);
C_Widget* f_ui_创建f32值编辑框(S_UI创建环境& ctx, S_Props& prop);*/


C_Widget*	f_ui_创建文件对话框(fp_文件处理回调 fun, std::string 初始路径, S_UI创建环境& ctx);
void		f_ui_设置文件对话框类型(C_Widget* fw, E_对话框类型 type);

C_Widget*	f_ui_创建曲线采样器(S_UI创建环境& ctx);
void		f_ui_曲线采样器绑定属性数据(C_Widget* self, S_Props& prop);

C_Widget*	f_ui_创建标签(S_UI创建环境& ctx);
void		f_ui_绑定标签属性(C_Widget* self, S_Props& prop);


C_Widget*	f_ui_创建图像框(S_UI创建环境& ctx);
C_Widget*	f_ui_创建过程纹理图像框(S_UI创建环境& ctx);
void		f_ui_bind图像框纹理属性(C_Widget* self, S_Props& prop);


C_Widget*		f_ui_get滚动框视口(C_Widget* self);
S_Props*		f_ui_get编辑框数值属性(C_Widget* self);
std::wstring	f_ui_get编辑框文本(C_Widget* self);
C_Widget*		f_ui_get选项夹页面(C_Widget* w, uint16 id);
C_文本框*		f_ui_from滚动框取文本视口(C_Widget* self);



void f_ui_设置按钮操作符(C_Widget* self, S_Props& op);
void f_ui_添加菜单项(C_Widget* self, S_菜单创建参数 pip, S_UI创建环境& ctx, uint16 layers=0);
void f_ui_打开菜单(C_Widget* self, vec2 pos);
void f_ui_填充列表(C_Widget* list, std::vector<S_列表填充数据>& items);
//void f_ui_打开对话框(C_Widget管理* gm, C_Widget* w, std::string path, std::string 后缀);
void f_ui_打开对话框(C_Widget管理* gm, C_Widget* w, E_对话框类型 type, fp_文件处理回调 fun, std::string path, std::string 后缀);
void f_ui_关闭对话框(C_Widget管理* gm, C_Widget* w, uint16 id);
uint32 f_ui_多页面添加页面(C_Widget* w, C_Widget* page, int8 loc = -1);
void f_ui_设置多页面头(C_Widget* w, vec2 size);
void f_ui_设置多页面标签文本(C_Widget* w, uint16 id, const std::wstring& text);

void f_ui_set图像视口纹理(C_Widget* w, S_纹理* tex, uint32 frameOffset);
void f_ui_图像视口填充捕捉点(C_Widget* w, std::vector<S_Rect2Df>& 点坐标, std::vector<S_RGBA8UI>& 点颜色);
void f_ui_图像视口_设置选区(C_Widget* w, const S_Rect2Df& 点坐标, const S_RGBA8UI& 点颜色 = { 100, 100, 255, 255 });
void f_ui_图像视口_关闭选区(C_Widget* w);

void f_ui_设置bool值编辑框引用值(C_Widget* w,	S_Props prop);
void f_ui_设置数值编辑框引用值(C_Widget* w, S_Props prop);
void f_ui_刷新数值编辑框绘制(C_Widget* w);
void f_ui_设置vec编辑框引用值(C_Widget* w,	S_Props prop);
void f_ui_刷新vec编辑框文本绘制(C_Widget* w);
void f_ui_文本框插入行文本(C_Widget* w, std::wstring text, int32 行 = -1);

bool f_ui_编辑框开关编辑(C_Widget* self, bool open);
void f_ui_数值部件文本到数值(C_Widget	*self);
void f_ui_set数值部件布尔值(C_Widget	*self);
bool f_ui_文本部件完成输入(C_Widget		*self);
void f_ui_set文本框框选回调(C_Widget* self, fp_Widget更新 选时, fp_Widget更新 选后);
vec2 f_ui_行编辑框光标位置(C_Widget		*self);
bool f_ui_文本部件全选(C_Widget* self, uvec2 range);
void f_ui_set文本编辑框文本(C_Widget* self, S_文档文本& txt);
void f_ui_set行文本框文本(C_Widget* self, std::wstring text);
void f_ui_setVec布局方向(C_Widget* self, E_方向 方向);
void f_ui_set枚举选择框图标和文字是否绘制(C_Widget* self, bool 是否绘制图标, bool 是否绘制标题);
void f_ui_set多页面添加事件(C_Widget* self, fp_Widget鼠标按键 切换回调, vec2 size);
void f_ui_set多页面当前页面(C_Widget* self, uint32 id);

void		f_ui_3D视口渲染(C_Widget			*self);
S_Rect2Df	f_ui_get视口(C_Widget* self);
void		f_ui_set3D视口部件帧绘制(C_Widget* self, bool 暂停);

//递归设置部件下所有子部件的画布引用
void		f_ui_set子部件的画布所在部件(C_Widget* self, C_Widget* 画布所在部件);


float32*	f_ui_getVec数据指针(C_Widget* self);
float32*	f_ui_getVec数据指针(C_Widget* self, uint8 loc);
S_Props*	f_ui_getVec数据(C_Widget* self);
S_文档文本* f_ui_get文档数据(C_Widget* self);
uint32		f_ui_get文档文本总字符数(const S_文档文本& doc);
//void f_link下层组件绘制函数(C_Widget* root, fp_WidgetDraw fun, uint16 key);
ubvec2		f_ui_get枚举表当前值(C_Widget* self);
uint8		f_ui_get枚举表项ID(C_Widget* self, uint8 子部件ID, bool 排除激活项 = true);
//uint32		f_ui_get枚举表GPU内存偏移(C_Widget* self, uint8 项ID);
bool		f_ui_get枚举表是否为激活项(C_Widget* self, uint8 项ID);
S_摄像机*	f_ui_get3D视口摄像机(C_Widget* self);
void        f_ui_set3D视口摄像机(C_Widget* self, S_摄像机* camera);
void        f_ui_set3D视口默认摄像机(C_Widget* self);
bool        f_ui_set3D视口是否为默认摄像机(C_Widget* self);



bool		f_ui_路径编辑框打开对话框(C_Widget* self, C_Widget管理* gm);
bool		f_ui_路径编辑框是否打开(C_Widget* self);



//void f_创建3D帧渲染层(S_Scene* scene, );

void		f_ui_bind文本编辑框文档(C_Widget* self, S_文档文本* doc);
void		f_ui_bind路径编辑框属性(C_Widget* self, S_Props* p);
void		f_ui_bind多选框属性(C_Widget* self, S_Props& p, E_方向 方向);
void		f_ui_bind枚举部件属性(C_Widget* w, S_Props& prop);

void		f_ui_set路径编辑框对话框类型(C_Widget* self, E_对话框类型 对话框类型);
void		f_ui_set路径编辑框对话框后缀(C_Widget* self, std::string 后缀);


void	f_ui_映射枚举组件绘制颜色(C_Widget* self, C_Widget* 分身);



void f_widget_layout_V滚动钳制(float32& 当前滚动坐标, float32 size, ivec2 行列, float32 项高度, uint32 num);



void f_部件设置布局(C_Widget* w, E_布局方式 方式);
void f_ui_组件布局(C_Widget管理* gm, const vec4& area);
void f_ui_筛选焦点组件(C_Widget管理* gm, const vec2& point);
void f_ui_执行输入设备事件(C_Widget管理* gm, const S_输入环境& input);


void f_ui_更新UI部件属性(C_Widget管理* gm, ivec2 view);
void f_ui_动态销毁UI部件(C_Widget管理* gm);
void f_ui_绘制组件(C_Widget管理* gm);
void f_ui_绘制到屏幕(C_Widget管理* gm, ivec2 view);

//void f_帧缓冲绘制屏幕(C_Widget管理* gm);
//void f_子组件裁剪(C_Widget* w, const vec4& area);
//void f_更新UI动画(C_Widget管理* gm);

void f_ui_统一映射GPU内存();
void f_ui_统一解映射GPU内存();
void f_ui_统一分配GPU内存();



void f_ui_push纹理填充(S_纹理* tex, uint8* data, uvec3 dim);
void f_ui_run纹理填充();




uint16 f_ui_管理器添加根部件(C_Widget管理* gm, C_Widget* w);
//里面执行组件打开回调函数
void f_ui_switchRootWidget(C_Widget管理* gm, uint16 id);





vec2 f_ui_get空间投影比例(const S_Rect2Df& rect, C_Mat44& 投影矩阵, float32 视点距离);
vec2 f_ui_get空间投影比例(const S_Rect2Df& rect, const S_摄像机& 摄像机);





void	f_ui_注册全局快捷键(std::vector<uint8>& Key, fp_Widget全局按键按下 func);
void	f_ui_注册全局快捷键(const S_键盘键位映射& Key);
void	f_ui_注册全局鼠标快捷键(const S_鼠标键位映射& Key);
void	f_ui_注册键盘快捷键(C_Widget* self, E_键位操作类型 操作类型, fp_Widget快捷键事件 event, uint8 any, bool ctrl = false, bool shift = false, bool alt = false);
void	f_ui_注册鼠标快捷键(C_Widget* self, E_键位操作类型 操作类型, fp_Widget快捷键事件 event, E_Input_鼠标按键 any, bool ctrl = false, bool shift = false, bool alt = false);
void	f_ui_注册键盘快捷键(C_Widget* self, S_键盘键位映射* km);
void	f_ui_注册鼠标快捷键(C_Widget* self, S_键位映射* km);




void f_ui主题_绘制按钮();
void f_ui添加图标组(C_Widget管理* gm, std::vector<S_纹理组添加参数> 添加参数);
void f_ui加载字体(S_UI创建环境* ctx, const std::vector<S_字体加载参数>& 添加参数);

void f_ui_释放图标组(C_Widget管理* gm);
void f_ui_释放字体(C_Widget管理* gm);



void f_ui_文件拖入(C_Widget管理* gm, const vec2& point);





/*
* 
* 
*  易错部分 
GPU参数修改回调函数要和画布部件是同一个对象,否则造成参数修改先行绘制构建函数.

面图元顶点数据类型
S_2D元素顶点

线图元顶点数据类型
S_2D线图元顶点

*/

/*
void f_ui_设置i8值编辑框引用值(C_Widget* w, S_Props prop);
void f_ui_设置ui8值编辑框引用值(C_Widget* w, S_Props prop);
void f_ui_设置i32值编辑框引用值(C_Widget* w, S_Props prop);
void f_ui_设置f32值编辑框引用值(C_Widget* w, S_Props prop);
*/





//------------------------------------ 废弃 -----------------------------------------------
C_Widget* f_ui_创建数值编辑框(S_UI创建环境& ctx, S_Props& prop, fp_Widget文本回调 f文本输入, fp_Widget文本输入完成 f输入完成);
C_Widget* f_ui_创建vec编辑框(S_UI创建环境& ctx, S_Props& prop, fp_Widget文本回调 f文本输入, fp_Widget文本输入完成 f输入完成, fp_Widget鼠标按键 f鼠标点击);



